﻿/*----------------------------------------------------------------
//  <copyright file="FunctionController.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2023-11-22 14:59</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.Api.Authorization.Areas.Admin.Controllers.Auth
{
    #region "功能管理"
    /// <summary>
    /// 功能管理
    /// </summary>
    [Description("功能管理")]
    [ModuleInfo(Code = "Function", Name = "功能管理", OrderNo = 2, Position = "Auth", PositionName = "授权模块")]
    public class FunctionController : AdminControllerBase
    {
        #region "属性"
        #region "获取 功能权限管理器"
        /// <summary>
        /// 获取 功能权限管理器
        /// </summary>
        protected FunctionAuthManager FunctionAuthManager => ServiceProvider.GetService<FunctionAuthManager>();
        #endregion

        #endregion

        #region "Action方法"
        #region "读取功能"
        /// <summary>
        /// 读取功能
        /// </summary>
        /// <param name="request">分页请求</param>
        /// <returns>功能信息集合</returns>
        [HttpPost]
        [ModuleInfo]
        [Description("读取")]
        public virtual PageData<FunctionOutputDto> Read(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            request.AddDefaultSortCondition(
                new SortCondition("Area"),
                new SortCondition("Controller"),
                new SortCondition("IsController", ListSortDirection.Descending));

            Expression<Func<Function, bool>> predicate = FilterService.GetExpression<Function>(request.FilterGroup);
            PageResult<FunctionOutputDto> page = CacheService.ToPageCache<Function, FunctionOutputDto>(FunctionAuthManager.Functions, predicate, request.PageCondition, function);
            return page.ToPageData();
        }
        #endregion
        #region "读取功能[模块]树"
        /// <summary>
        /// 读取功能[模块]树
        /// </summary>
        /// <param name="moduleId">模块编号</param>
        /// <returns>功能[模块]树数据</returns>
        [HttpGet]
        [ModuleInfo]
        [Description("读取[模块]树")]
        public virtual TreeNode[] ReadTreeNode(long moduleId)
        {
            Check.GreaterThan(moduleId, nameof(moduleId), 0);

            IFunction function = this.GetExecuteFunction();
            Expression<Func<ModuleFunction, bool>> exp = m => m.ModuleId == moduleId;

            var checkFuncIds = CacheService.ToCacheArray(FunctionAuthManager.ModuleFunctions, exp, m => m.FunctionId, function);
            //Guid[] checkFuncIds = _functionAuthManager.ModuleFunctions.Where(m => m.ModuleId == moduleId).Select(m => m.FunctionId).ToArray();

            Expression<Func<Function, bool>> exp2 = m => m.Area == null || m.Area.ToUpper() == "Admin".ToUpper();
            var groups = CacheService.ToCacheList(FunctionAuthManager.Functions.Unlocked(), exp2, m => new
            {
                m.Id,
                m.Name,
                m.Area,
                m.Controller,
                m.Action,
                m.IsController,
                m.AccessType
            }, function).GroupBy(m => m.Area).OrderBy(m => m.Key).ToList();
            //var groups = _functionAuthManager.Functions.Unlocked()
            //    .Where(m => m.Area == null || m.Area == "Admin")
            //    .Select(m => new
            //    {
            //        m.Id,
            //        m.Name,
            //        m.Area,
            //        m.Controller,
            //        m.Action,
            //        m.IsController,
            //        m.AccessType
            //    }).ToList().GroupBy(m => m.Area).OrderBy(m => m.Key).ToList();

            TreeNode root = new()
            {
                Id = Guid.NewGuid().ToString("N"),
                Name = "系统",
            };
            foreach (var group1 in groups)
            {
                TreeNode areaNode = new() { Id = null, Name = group1.Key == null ? "网站" : group1.Key == "Admin" ? "管理" : "未知模块" };
                root.Items.Add(areaNode);
                var group2S = group1.GroupBy(m => m.Controller).OrderBy(m => m.Key).ToList();
                foreach (var group2 in group2S)
                {
                    //areaNode.HasChildren = true;
                    var controller = group2.First(m => m.Action == null);
                    TreeNode controllerNode = new() { Id = Guid.NewGuid().ToString("N"), Name = $"{controller.Name}[{controller.Controller}]" };
                    areaNode.Items.Add(controllerNode);
                    foreach (var action in group2.Where(m => m.Action != null).OrderBy(m => m.Action))
                    {
                        TreeNode actionNode = new()
                        {
                            Id = action.Id.ToString("N"),
                            Name = action.Area == null
                                ? $"{action.Name}[{action.Controller}/{action.Action}]"
                                : $"{action.Name}[{action.Area}/{action.Controller}/{action.Action}]",
                            Data = action.AccessType,
                            IsChecked = checkFuncIds.Contains(action.Id)
                        };
                        controllerNode.Items.Add(actionNode);
                    }
                }
            }
            return new[] { root };
        }
        #endregion

        #region "更新功能"
        /// <summary>
        /// 更新功能
        /// </summary>
        /// <param name="dtos">功能信息</param>
        /// <returns>JSON操作结果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction(nameof(Read))]
        [Description("更新")]
        public virtual async Task<AjaxResult> Update(params FunctionInputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));

            OperationResult result = await FunctionAuthManager.UpdateFunctions(dtos);
            return result.ToAjaxResult(true);
        }
        #endregion

        #endregion

    }
    #endregion

}
